package vip.manda.framework.web.http;

import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import vip.manda.framework.config.WebConfig;
import vip.manda.framework.core.Configs;
import vip.manda.framework.log.Log;
import vip.manda.framework.log.LogFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @author hongda.li 2022-04-12 09:46
 */
public class StaticResourceHandler {
    public static final Map<String, String> CONTENT_TYPES = new HashMap<>(16);

    static {
        CONTENT_TYPES.put(".html", "text/html;charset=utf-8");
        CONTENT_TYPES.put(".css", "text/css");
        CONTENT_TYPES.put(".json", "application/json;charset=utf-8");
        CONTENT_TYPES.put(".js", "text/javascript");
        CONTENT_TYPES.put(".jpg", "image/jpeg");
        CONTENT_TYPES.put(".png", "image/png");
        CONTENT_TYPES.put(".ico", "image/x-icon");
    }

    private final Log log = LogFactory.getLog();
    private final File root;
    private final String uri;
    private final HttpServletResponse response;
    private final boolean isClassPath;

    public StaticResourceHandler(HttpServletRequest request, HttpServletResponse response) {
        String root = Configs.getStr(WebConfig.ROOT);
        if (root.startsWith(WebConfig.Value.ROOT)) {
            this.isClassPath = true;
            this.root = null;
        } else {
            this.isClassPath = false;
            this.root = new File(root);
        }
        this.uri = request.getRequestURI();
        this.response = response;
    }

    public boolean checkStaticResource() {
        return StrUtil.endWithAny(uri, ".html", ".css", ".js", ".png", ".jpg", ".ico");
    }

    public void handle() throws IOException {
        if (isClassPath) {
            handleClassPath();
        } else {
            handleWebRoot();
        }
    }

    private void handleClassPath() {
        response.setContentType(CONTENT_TYPES.get(uri.substring(uri.lastIndexOf("."))));
        try {
            response.getWriter().write(ResourceUtil.readStr(uri, StandardCharsets.UTF_8));
        } catch (Exception e) {
            log.debug("Static resource doesn't exists[{}]", uri);
        }
    }

    private void handleWebRoot() throws IOException {
        boolean exists = root.exists();
        if (!exists) {
            log.error("Web root doesn't exists[{}]", root);
            return;
        }
        File file = new File(root.getAbsolutePath() + uri);
        if (file.exists()) {
            response.setContentType(CONTENT_TYPES.get(uri.substring(uri.lastIndexOf("."))));
            FileReader reader = new FileReader(file);
            response.getWriter().write(reader.readString());
        } else {
            log.debug("Static resource doesn't exists[{}]", uri);
        }
    }
}
